The present invention relates generally to the field of computer code compilation, and more particularly to compiler optimization.
Java is a well-known, class-based, object-oriented computer programming language. (Note: the term “JAVA” may be subject to trademark rights in various jurisdictions throughout the world and is used here only in reference to the products or services properly denominated by the mark to the extent that such trademark rights may exist.) In the stylized case, translating Java source code into machine-executable code is a two-stage process. In the first stage, Java source code from a .java file is compiled into bytecode—an intermediate, platform-independent representation of the code that can be run on any Java Virtual Machine (JVM)—that is then saved into a .class file. Then, at runtime, a JVM converts the bytecode in the .class file into native executable machine code on the target platform. This second conversion is often performed by a compiler as well, whether of the ahead-of-time (AOT) or just-in-time (JIT) varieties, which may use a number of optimization techniques to improve the code's runtime performance.
Two well-known optimization techniques are function inlining and profile-guided optimization (PGO). With function inlining—also known as inline expansion, or simply “inlining”—a call to a function is replaced by the body of the function itself. Inlining thereby avoids the overhead associated with making a function call, and, when used appropriately, can consequently improve the time and/or space performance of the code at runtime. Profile-guided optimization, as the name suggests, involves the evaluation of prior runtime behavior to guide selection of the most advantageous optimizations for the present compilation.
A class in object-oriented programming is an extensible template for creating objects, which are collections of values (data or data structures) and/or behaviors (member functions, or methods). A child class may be derived from one or more parent classes, in which case the child generally inherits the template of the parent and extends it through additional data fields and/or methods. If a parent contains a virtual function or method, a derived class may override that function by specifying behavior different from that of the parent when that function is invoked for an object of the derived class.
For the most part, classes in Java are loaded into a JVM at runtime by Java objects called class loaders. Caching loaded classes can save time in servicing subsequent requests for those classes, and in some implementations, cached classes may be shared among multiple JVMs through one or more shared class caches. Both class bytecode and native compiled code may be persisted through such caches.
The Java heap is memory available to a JVM for dynamic memory allocation. Allocated memory in the heap is freed through the process of garbage collection, whereby a set of roots is traversed for any reference to an object in memory, and if no reference is found, the memory allocated to that object is released. Other objects may be repositioned in the heap during this process as well.
A hash table, or hash map, is a commonly used data structure used to map keys to values. A hash table maps keys to values using a hash function, such that applying the hash function to a provided key produces an index into an array of values. Hash tables are popular because they are often more efficient than other table lookup functions, with well-designed hash tables being able to achieve a constant-order cost of operations independent of table size. However, hash functions cannot usually guarantee that every key will map to a unique index, so some form of collision detection and resolution must often be used as well. One example of this is separate chaining, where each index may be associated with a short list of key-value pairs: the hash function does the bulk of the searching (or sorting) work, while the few entries that remain are searched (or sorted) by some other method.